<?php
/**
 * Mysql接口类
 * 
 * @version $Id: Mysql.php 210 2011-07-13 09:44:29Z linsir123 $
 */

/**
 * 对象
 */
define('OBJECT', 'OBJECT');

/**
 * 字符下标的数组
 */
define('ARRAY_A', 'ARRAY_A');

/**
 * 数字下标的数组
 */
define('ARRAY_N', 'ARRAY_N');

/**
 * Mysql接口类
 */
class Mysql
{
	/**
	 * @var 数据操作次数
	 */
	public $numQuery = 0;
	
	/**
	 * @var 数据可操作状态
	 */
	public $ready;
	
	/**
	 * @var 是否开启调试
	 */
	public $debug;
	
	/// 
	public $dbh;
	public $dbname;
	public $queries;
	public $insertId = 0;
	public $rowsAffected = 0;
	public $numRows = 0;
	public $result;
	public $error;
	
	/**
	 * 构造函数
	 */
	function __construct($dsnNumber = 0)
	{
		$app = App::instance();
		
		///
		$this->ready = true;
		$this->debug = APP_DEBUG;
		$charset = $app->charset['db'];
		list($host, $user, $pwd, $this->dbname) = $app->dsn[$dsnNumber];
		
		///
		if (!$this->dbh = @mysql_connect($host, $user, $pwd, true)) 
			throw new Exception("无法连接到[Mysql]服务器({$host})，通过用户({$user})。");
			
		if (!@mysql_select_db($this->dbname, $this->dbh)) 
			throw new Exception("数据库({$this->dbname})不存在。");
		
		if (!empty($charset) && $this->supportCollation()) 
			@mysql_query("SET NAMES '{$charset}'");
	}
	
	/**
	 * 析构函数
	 */
	function __destruct()
	{
		if (is_resource($this->dbh)) 
			@mysql_close($this->dbh);
	}
	
	/**
	 * 数据操作,查询
	 */
	function query($query)
	{
		if (!$this->ready) 
			return false;
		
		$returnVal = 0;
		$this->insertId = 0;
		$this->result = array();
		
		if ($this->debug) 
			$this->timerStart();
		
		$res = @mysql_query($query, $this->dbh);
		++$this->numQuery;
		
		if ($this->debug) 
			$this->queries[] = array($query, $this->timerStop());
		
		if ($this->error = mysql_error($this->dbh)) {
			$this->bail($query);
			return false;
		}
		
		if (preg_match("/^\\s*(insert|delete|update|replace) /i", $query)) {
			$this->rowsAffected = mysql_affected_rows($this->dbh);
			if (preg_match("/^\\s*(insert|replace) /i", $query)) 
				$this->insertId = mysql_insert_id($this->dbh);
			
			$returnVal = $this->rowsAffected;
		} else {
			$numRows = 0;
			while ($row = @mysql_fetch_object($res)) {
				$this->result[$numRows] = $row;
				$numRows++;
			}
			
			@mysql_free_result($res);
			$returnVal = $this->numRows = $numRows;
		}
		
		return $returnVal;
	}
	
	/**
	 * 数据结构操作
	 */
	function operate($query)
	{
		return mysql_query($query);
	}
	
	/**
	 * 取得某个值
	 */
	function getVar($query = null, $x = 0, $y = 0)
	{
		if ($query) 
			$this->query($query);
		
		if (!empty($this->result[$y])) 
			$values = array_values(get_object_vars($this->result[$y]));
		
		return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
	}
	
	/**
	 * 取得某行记录
	 */
	function getRow($query = null, $output = ARRAY_A, $y = 0)
	{
		if ($query) 
			$this->query($query);
		
		if (!isset($this->result[$y])) 
			return null;
		
		if ($row = $this->result[$y]) {
			if ($output == ARRAY_A) 
				$row = get_object_vars($row);
			elseif ($output == ARRAY_N) 
				$row = array_values(get_object_vars($row));
		}
		
		return $row;
	}
	
	/**
	 * 取得某列字段值
	 */
	function getCol($query = null , $x = 0)
	{
		if ($query) 
			$this->query($query);
		
		$newArray = array();
		for ($i = 0; $i < count($this->result); $i++) 
			$newArray[$i] = $this->getVar(null, $x, $i);
		
		return $newArray;
	}
	
	/**
	 * 取得所有记录
	 */
	function getResults($query = null, $output = ARRAY_A)
	{
		if ($query) 
			$this->query($query);
		
		if ($result = $this->result) {
			if ($output != OBJECT) {
				$i = 0;
				$newArray = array();
				foreach($result as $row) {
					if ($output == ARRAY_A) 
						$newArray[$i] = get_object_vars($row);
					elseif ($output == ARRAY_N) 
						$newArray[$i] = array_values(get_object_vars($row));
						
					++$i;
				}
				
				$result = $newArray;
			}
		}
		
		return $result;
	}
	
	/**
	 * 取得数据库的数据表名
	 */
	function getTables()
	{
		$newArray = array();
		if ($result = mysql_list_tables($this->dbname, $this->dbh)) {
			while ($row = mysql_fetch_row($result)) 
				array_push($newArray, $row[0]);
			
			mysql_free_result($result);
		}
		
		return $newArray;
	}
	
	/**
	 * 判断某个表是否存在
	 */
	function existsTable($table)
	{
		$query = "SHOW TABLES LIKE '{$table}'";
		$result = mysql_query($query);
		$exists = false;
		while ($row = mysql_fetch_array($result)) {
			$exists = true;
			break;
		}
		
		return $exists;
	}
	
	/**
	 * 取得Mysql版本信息
	 */
	function version()
	{
		return mysql_get_server_info($this->dbh);
	}
	
	/**
	 * 取得Mysql对字符集的支持
	 */
	function supportCollation()
	{
		return (version_compare(mysql_get_server_info($this->dbh), '4.1.0', '>='));
	}
	
	/**
	 * 开启计时器
	 */
	function timerStart()
	{
		$mtime = explode(' ', microtime());
		$this->timeStart = $mtime[1] + $mtime[0];
		return true;
	}
	
	/**
	 * 关闭计时器
	 */
	function timerStop()
	{
		$mtime = explode(' ', microtime());
		return $mtime[1] + $mtime[0] - $this->timeStart;
	}
	
	/**
	 * 操作语句出错处理
	 */
	function bail($query)
	{
		$content = $query.'('.mysql_error().' ['.mysql_errno().'])';
		App::log($content);
	}
}
